home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / AIFF_DSP_v15 folder / AIFF_DSP / sintab.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  2.8 KB  |  96 lines  |  [TEXT/KAHL]

  1. /*
  2. FILE:    sintab.c
  3. PROJECT: Ford grant DSP
  4. AUTHOR:  Ben Denckla
  5. COMMENT: sine table generation & lookup
  6. */
  7.  
  8. #include "aiff.h"
  9. #include "sintab.h"
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <math.h>   // must come before SANE #include to have precedence
  14. #include <SANE.h>
  15.  
  16. #define HALFPI  1.5707963 // half of pi
  17. #define SINAMP  0x7FFF    // sine wave amplitude
  18.  
  19. short sintab[QSIZ+1];
  20.  
  21. DEFFUNC( double round( double x )) {
  22.     double offset = 0.5;
  23.     if( x < 0.0 ) offset = -offset;
  24.     return  x + offset;
  25. }
  26.  
  27. // puts a 1st-quadrant sine table into sintab[]
  28. void get_sintab ( void ) {
  29.     short i;
  30.     double rads;
  31.     
  32.     sintab[0]    = 0;
  33.     sintab[QSIZ] = SINAMP;
  34.     for (i=1; i < QSIZ; i++)
  35.         sintab[i] = round( SINAMP * sin( HALFPI * i / QSIZ ) );
  36. }
  37. /*
  38. 1. Small enough means that the correct last value is found where expected.
  39. 2. Does not deserve a call to exit because a file error here does not impede
  40.    function of program and therefore is not a fatal error.
  41. */
  42.  
  43. // puts a full 4-quadrant sine table into sintab4[] using sintab()
  44. short *gen_sintab4 ( void ) {
  45.     unsigned short i;
  46.     short *sintab4, *tsintab4;
  47.  
  48.     if (!(sintab4 = malloc( 2L*4*QSIZ )))
  49.         err( "Could not allocate 4-quadrant sine table memory" );
  50.  
  51.     tsintab4 = sintab4;
  52.     for (i=0; i<4*QSIZ; i++)
  53.         *tsintab4++ = sin_tab( i );
  54.     return sintab4;
  55. }
  56.  
  57. // returns SINAMP * sin (pi/2 * tabi/QSIZ) using sintab[]
  58. // tabi is assumed to be non-negative
  59. short sin_tab( short tabi ) {
  60.     register short i;
  61.  
  62.     i = tabi & (2*QSIZ-1); // i = tabi % 2QSIZ;
  63.     if ( i & QSIZ )        // if ( i >= QSIZ )
  64.         i = 2*QSIZ - i;    // reflect i from the 2nd to the 1st quadrant
  65.     if ( tabi & (2*QSIZ) ) // if ( (tabi % 4QSIZ) >= 2QSIZ )
  66.         return -sintab[i]; // negate sintab[i] if in 3rd or 4th quadrant
  67.     else return sintab[i];
  68. }
  69.  
  70. // getusrharm() asks the user for a frequency and returns number of the
  71. // closest harmonic of the sine table frequency
  72. short getusrharm() {
  73.     double infreq, oufreq, tabfreq, centerr;
  74.     short retval;
  75.  
  76.     GETNUMRANGE( "frequency", "%.1lf", "%lf", infreq, 0.0, ph.rate/2 );
  77.  
  78.     tabfreq = ph.rate / (4*QSIZ);    // sine table frequency (1)
  79.     retval = infreq / tabfreq + 0.5; // (2)
  80.     if (!retval) retval++;           // bump 0th harmonic up to 1st
  81.     oufreq = tabfreq * retval;       // output frequency
  82.     if (oufreq > ph.rate/2) {        // if Nyquist freq. exceeded
  83.         oufreq -= tabfreq;            // bump oufreq down 1 harmonic
  84.         retval--;                     // bump retval down 1 harmonic
  85.     }
  86.     centerr = 1200 * log( oufreq/infreq ) / log(2);            // 3
  87.     printf( "\tUsing %.3f Hz, %.3f Hz or %.1f cents away\n\n",
  88.         oufreq, oufreq - infreq, centerr );
  89.     return retval;
  90. }
  91. /*
  92. 1. sine table frequency >= 1 Hz ==> 4*QSIZ <= 44100 < 0x10000 ==> 4*QSIZ
  93.     fits in an unsigned word.
  94. 2. harmonic of tabfreq closest to infreq (+ 0.5 rounds).
  95. 3. cent error is the interval between oufreq and infreq
  96. */